package com.jintian.smart.kernel.orm.sql;

import cn.hutool.core.lang.Dict;
import org.beetl.sql.core.query.QueryCondition;
import org.beetl.sql.core.query.interfacer.StrongValue;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

public class SqlUpdate {
    private String tableName;

    private Dict fields;

    private SqlCondition condition;

    private String sql;

    private List<Object> params;

    public SqlUpdate() {
        init();
    }

    public SqlUpdate(String tableName, Dict fields, SqlCondition condition) {
        this.tableName = tableName;
        this.fields = fields;
        this.condition = condition;

        init();
    }

    private void init() {
        if (fields == null) {
            fields = new Dict();
        }
        if (condition == null) {
            condition = new SqlCondition();
        }
        if (params == null) {
            params = new ArrayList<>();
        }
    }

    public SqlUpdate setTable(String tableName) {
        this.tableName = tableName;
        return this;
    }

    public SqlUpdate setField(String field, Object value) {
        this.fields.put(field, value);
        return this;
    }

    public SqlUpdate setCondition(SqlCondition condition) {
        this.condition = condition;
        return this;
    }

    public SqlUpdate build() {
        params = new ArrayList<>();

        StringBuilder builder = new StringBuilder("UPDATE ");
        builder.append(tableName);
        builder.append(" SET ");
        boolean first = true;
        for (String key : fields.keySet()) {
            if (!first) {
                builder.append(", ");
                first = false;
            }
            builder.append(key);
            builder.append(" = ?");
            params.add(fields.get(key));
        }
        builder.append(" ");
        builder.append(condition.getSql());

        sql = builder.toString();
        params.addAll(condition.getParams());
        return this;
    }

    public String getSql() {
        return sql;
    }

    public Object[] getParams() {
        return params.toArray();
    }

    public SqlUpdate andEq(String column, Object value) {
        condition.andEq(column, value);
        return this;
    }

    public SqlUpdate andNotEq(String column, Object value) {
        condition.andNotEq(column, value);
        return this;
    }

    /**
     * 大于
     */
    public SqlUpdate andGreat(String column, Object value) {
        condition.andGreat(column, value);
        return this;
    }

    /**
     * 大于等于
     */
    public SqlUpdate andGreatEq(String column, Object value) {
        condition.andGreatEq(column, value);
        return this;
    }

    /**
     * 小于
     */
    public SqlUpdate andLess(String column, Object value) {
        condition.andLess(column, value);
        return this;
    }

    /**
     * 小于等于
     */
    public SqlUpdate andLessEq(String column, Object value) {
        condition.andLessEq(column, value);
        return this;
    }

    public SqlUpdate andLike(String column, Object value) {
        condition.andLike(column, value);
        return this;
    }

    public SqlUpdate andNotLike(String column, Object value) {
        condition.andNotLike(column, value);
        return this;
    }

    public SqlUpdate andIsNull(String column) {
        condition.andIsNull(column);
        return this;
    }

    public SqlUpdate andIsNotNull(String column) {
        condition.andIsNotNull(column);
        return this;
    }

    public SqlUpdate andIn(String column, Collection<?> value) {
        condition.andIn(column, value);
        return this;
    }

    public SqlUpdate andIn(String column, StrongValue value) {
        condition.andIn(column, value);
        return this;
    }

    public SqlUpdate andIn(String column, Optional value) {
        condition.andIn(column, value);
        return this;
    }

    public SqlUpdate andNotIn(String column, Collection<?> value) {
        condition.andNotIn(column, value);
        return this;
    }

    public SqlUpdate andNotIn(String column, StrongValue value) {
        condition.andNotIn(column, value);
        return this;
    }

    public SqlUpdate andNotIn(String column, Optional value) {
        condition.andNotIn(column, value);
        return this;
    }


    public SqlUpdate andBetween(String column, Object value1, Object value2) {
        condition.andBetween(column, value1, value2);
        return this;
    }


    public SqlUpdate andNotBetween(String column, Object value1, Object value2) {
        condition.andNotBetween(column, value1, value2);
        return this;
    }


    public SqlUpdate orEq(String column, Object value) {
        condition.orEq(column, value);
        return this;
    }


    public SqlUpdate orNotEq(String column, Object value) {
        condition.orNotEq(column, value);
        return this;
    }

    /**
     * 大于
     */

    public SqlUpdate orGreat(String column, Object value) {
        condition.orGreat(column, value);
        return this;
    }

    /**
     * 大于等于
     */

    public SqlUpdate orGreatEq(String column, Object value) {
        condition.orGreatEq(column, value);
        return this;
    }

    /**
     * 小于
     */

    public SqlUpdate orLess(String column, Object value) {
        condition.orLess(column, value);
        return this;
    }

    /**
     * 小于等于
     */

    public SqlUpdate orLessEq(String column, Object value) {
        condition.orLessEq(column, value);
        return this;
    }


    public SqlUpdate orLike(String column, Object value) {
        condition.orLike(column, value);
        return this;
    }


    public SqlUpdate orNotLike(String column, Object value) {
        condition.orNotLike(column, value);
        return this;
    }


    public SqlUpdate orIsNull(String column) {
        condition.orIsNull(column);
        return this;
    }


    public SqlUpdate orIsNotNull(String column) {
        condition.orIsNotNull(column);
        return this;
    }


    public SqlUpdate orIn(String column, Collection<?> value) {
        condition.orIn(column, value);
        return this;
    }


    public SqlUpdate orIn(String column, StrongValue value) {
        condition.orIn(column, value);
        return this;
    }


    public SqlUpdate orIn(String column, Optional value) {
        condition.orIn(column, value);
        return this;
    }


    public SqlUpdate orNotIn(String column, Collection<?> value) {
        condition.orNotIn(column, value);
        return this;
    }


    public SqlUpdate orNotIn(String column, StrongValue value) {
        condition.orNotIn(column, value);
        return this;
    }


    public SqlUpdate orNotIn(String column, Optional value) {
        condition.orNotIn(column, value);
        return this;
    }


    public SqlUpdate orBetween(String column, Object value1, Object value2) {
        condition.orBetween(column, value1, value2);
        return this;
    }


    public SqlUpdate orNotBetween(String column, Object value1, Object value2) {
        condition.orNotBetween(column, value1, value2);
        return this;
    }


    public SqlUpdate and(QueryCondition condition) {
        condition.and(condition);
        return this;
    }


    public SqlUpdate or(QueryCondition condition) {
        condition.or(condition);
        return this;
    }

    public static void main(String[] args) {
        SqlUpdate sqlUpdate = new SqlUpdate();
        sqlUpdate.setTable("dltb").setField("status", 1).andEq("id", "1212").build();
        System.out.println(sqlUpdate.getSql());
        Object[] params = sqlUpdate.getParams();
        String sql = sqlUpdate.getSql();
    }
}
